using UnityEngine;
using System;

public class Jogador : MonoBehaviour
{

	// movement config
	/*public float gravity = -25f;
	public float runSpeed = 8f;
	public float groundDamping = 20f; // how fast do we change direction? higher means faster
	public float inAirDamping = 5f;
	public float jumpHeight = 3f;*/

    public float gravity;
    public float walkSpeed;
    public float sprintSpeed;
    public float groundDamping; // how fast do we change direction? higher means faster
    public float inAirDamping;
    public float jumpHeight;
	
	[HideInInspector]
	private float normalizedHorizontalSpeed = 0;
	
	private CharacterController2D _controller;
	private Animator _animator;
	private RaycastHit2D _lastControllerColliderHit;
	private Vector3 _velocity;
    private float runSpeed;
    private int jumpLimit = 2;
    private static int jumpCount;

	// input
	private bool _right;
	private bool _left;
	private bool _up;
    private bool _sprintBtn;
	private bool _actionBtn;
	
	
	void Awake()
	{
		_animator = GetComponent<Animator>();
		_controller = GetComponent<CharacterController2D>();
		
		// listen to some events for illustration purposes
		_controller.onControllerCollidedEvent += onControllerCollider;
		_controller.onTriggerEnterEvent += onTriggerEnterEvent;
		_controller.onTriggerExitEvent += onTriggerExitEvent;
	}
	
	
	#region Event Listeners
	
	void onControllerCollider( RaycastHit2D hit )
	{
		// logs any collider hits if uncommented. it gets noisy so it is commented out for the demo
		//Debug.Log( "flags: " + _controller.collisionState + ", hit.normal: " + hit.normal );
	}
	
	
	void onTriggerEnterEvent( Collider2D col )
	{
		Debug.Log( "onTriggerEnterEvent: " + col.gameObject.name );
	}
	
	
	void onTriggerExitEvent( Collider2D col )
	{
		Debug.Log( "onTriggerExitEvent: " + col.gameObject.name );
	}
	
	#endregion
	
	
	// the Update loop only gathers input. Actual movement is handled in FixedUpdate because we are using the Physics system for movement
	void Update()
	{
		// a minor bit of trickery here. FixedUpdate sets _up to false so to ensure we never miss any jump presses we leave _up
		// set to true if it was true the previous frame
		_up = Input.GetKeyDown( KeyCode.UpArrow );
		_right = Input.GetKey( KeyCode.RightArrow );
		_left = Input.GetKey( KeyCode.LeftArrow );
        _sprintBtn = Input.GetKey(KeyCode.A);
		_actionBtn = Input.GetKey(KeyCode.S);
	}

	
	void FixedUpdate()
	{
		// grab our current _velocity to use as a base for all calculations
		_velocity = _controller.velocity;
		Debug.Log ("VEL:"+_velocity.x, this);
		if( _controller.isGrounded )
			_velocity.y = 0;

		if( _right )
		{
			normalizedHorizontalSpeed = 1;
			if( transform.localScale.x > 0f )
				transform.localScale = new Vector3( -transform.localScale.x, transform.localScale.y, transform.localScale.z );

			if( _controller.isGrounded == true ) {
				jumpCount = 0;
				/*if(Math.Abs(_velocity.x) > 130)
					_animator.Play( Animator.StringToHash( "Run" ) );
				else
					_animator.Play( Animator.StringToHash( "Walk" ) );*/

                if (_sprintBtn)
                {
                    _animator.Play(Animator.StringToHash("Run"));
                    runSpeed = sprintSpeed;
                }
                else
                {
                    _animator.Play(Animator.StringToHash("Walk"));
                    runSpeed = walkSpeed;
                }
			}

			//double jump
			if (_controller.isGrounded == false)
			{
				if(_up ){
					if(jumpCount < 1)
					{
						_velocity.y = Mathf.Sqrt(2f * jumpHeight * -gravity);
						_animator.Play(Animator.StringToHash("DoubleJump"));
						jumpCount++;
					}
				}
				
			} 
		}
		else if( _left )
		{
			normalizedHorizontalSpeed = -1;
			if( transform.localScale.x < 0f )
				transform.localScale = new Vector3( -transform.localScale.x, transform.localScale.y, transform.localScale.z );
			
			/*if( _controller.isGrounded )
				if(Math.Abs(_velocity.x) > 130)
					_animator.Play( Animator.StringToHash( "Run" ) );
			else
				_animator.Play( Animator.StringToHash( "Walk" ) );
             * */
			if( _controller.isGrounded == true) {
				jumpCount = 0;
	            if (_sprintBtn)
	            {
	                _animator.Play(Animator.StringToHash("Run"));
	                runSpeed = sprintSpeed;
	            }
	            else
	            {
	                _animator.Play(Animator.StringToHash("Walk"));
	                runSpeed = walkSpeed;
	            }
			}

			//double jump
			if (_controller.isGrounded == false)
			{
				if(_up ){
					if(jumpCount < 1)
					{
						_velocity.y = Mathf.Sqrt(2f * jumpHeight * -gravity);
						_animator.Play(Animator.StringToHash("DoubleJump"));
						jumpCount++;
					}
				}
				
			} 
		}
		else
		{
			normalizedHorizontalSpeed = 0;
			
			if( _controller.isGrounded == true )
				_animator.Play( Animator.StringToHash( "Iddle" ) );
                jumpCount = 0;
		}
		
		
		// we can only jump whilst grounded
		if( _controller.isGrounded == true && _up )
		{
			_velocity.y = Mathf.Sqrt( 2f * jumpHeight * -gravity );
			_animator.Play( Animator.StringToHash( "Jump" ) );
            jumpCount++;
		}

		//double jump
		if (_controller.isGrounded == false)
		{
			if(_up ){
				if(jumpCount < 1)
				{
					_velocity.y = Mathf.Sqrt(2f * jumpHeight * -gravity);
					_animator.Play(Animator.StringToHash("DoubleJump"));
					jumpCount++;
				}
			}
			
		} 
		
		if(_velocity.y < 1 && !_controller.isGrounded) {
			_animator.Play( Animator.StringToHash( "Fall" ) );
            if (_velocity.y < -520)
            {
                Respawn();
            }
		}
		
		
		// apply horizontal speed smoothing it
		var smoothedMovementFactor = _controller.isGrounded ? groundDamping : inAirDamping; // how fast do we change direction?
		_velocity.x = Mathf.Lerp( _velocity.x, normalizedHorizontalSpeed * runSpeed, Time.fixedDeltaTime * smoothedMovementFactor );
		
		// apply gravity before moving
		_velocity.y += gravity * Time.fixedDeltaTime;
		
		_controller.move( _velocity * Time.fixedDeltaTime );
		
		// reset input
		_up = false;
	}

    void Respawn()
    {
        transform.position = new Vector3(95, -510, 0);
    }

	void Shoot()
	{

	}
	
}

